package com.cskaoyan.market.service.impl;

import com.cskaoyan.market.vo.BrandVo;
import com.cskaoyan.market.vo.CategoryVo;
import com.cskaoyan.market.db.domain.*;
import com.cskaoyan.market.db.mapper.*;
import com.cskaoyan.market.service.AdminGoodsService;
import com.cskaoyan.market.util.MybatisUtil;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.SqlSession;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AdminGoodsServiceImpl implements AdminGoodsService {

    @Override
    public List<MarketGoods> list(String page, String limit, String sort, String order, String goodsId, String goodsSn, String name) {
        SqlSession session = MybatisUtil.getSession();
        MarketGoodsMapper mapper = session.getMapper(MarketGoodsMapper.class);
        MarketGoodsExample marketGoodsExample = new MarketGoodsExample();

        MarketGoodsExample.Criteria criteria = marketGoodsExample.createCriteria();
        if (!StringUtils.isEmpty(goodsId)) {
            criteria.andIdEqualTo(Integer.parseInt(goodsId));
        }
        if (!StringUtils.isEmpty(goodsSn)) {
            criteria.andGoodsSnEqualTo("%" + goodsSn + "%");
        }
        if (!StringUtils.isEmpty(name)) {
            criteria.andNameLike("%" + name + "%");
        }
        PageHelper.startPage(Integer.parseInt(page),Integer.parseInt(limit));
        marketGoodsExample.setOrderByClause(sort + " " + order);
        List<MarketGoods> marketGoods = mapper.selectByExample(marketGoodsExample);
        session.commit();
        session.close();
        return marketGoods;
    }

    @Override
    public Integer delete(String id) {
        SqlSession session = MybatisUtil.getSession();
        MarketGoodsMapper mapper = session.getMapper(MarketGoodsMapper.class);
        MarketGoodsExample marketGoodsExample = new MarketGoodsExample();
        MarketGoodsExample.Criteria criteria = marketGoodsExample.createCriteria();
        criteria.andIdEqualTo(Integer.parseInt(id));
        int i = mapper.deleteByExample(marketGoodsExample);
        session.commit();
        session.close();
        return i;
    }

    @Override
    public MarketGoods getGoodsDetail(String id) {
        SqlSession session = MybatisUtil.getSession();
        MarketGoodsMapper mapper = session.getMapper(MarketGoodsMapper.class);
        MarketGoodsExample marketGoodsExample = new MarketGoodsExample();
        MarketGoodsExample.Criteria criteria = marketGoodsExample.createCriteria();
        criteria.andIdEqualTo(Integer.parseInt(id));
        MarketGoods marketGoods = mapper.selectOneByExample(marketGoodsExample);
        session.commit();
        session.close();
        return marketGoods;
    }

    @Override
    public List<CategoryVo> categoryList() {
        SqlSession session = MybatisUtil.getSession();
        MarketCategoryMapper mapper = session.getMapper(MarketCategoryMapper.class);
        List<MarketCategory> marketCategoryList = mapper.selectByExample(new MarketCategoryExample());
        session.commit();
        session.close();

        Map<Integer, List<MarketCategory>> categoryGroupByPid = groupByPid(marketCategoryList);
        List<CategoryVo> categoryVoList = new ArrayList<>();
        List<MarketCategory> categoryList = categoryGroupByPid.get(0);
        for (MarketCategory parentCategory : categoryList) {
            CategoryVo categoryVo = new CategoryVo(parentCategory.getId(), parentCategory.getName(), null);
            List<CategoryVo> sonCategoryVoList = new ArrayList<>();
            List<MarketCategory> sonCategoryList = categoryGroupByPid.get(parentCategory.getId());
            if(sonCategoryList != null){
                for (MarketCategory sonCategory : sonCategoryList) {
                    CategoryVo sonCategoryVo = new CategoryVo(sonCategory.getId(), sonCategory.getName(),null);
                    sonCategoryVoList.add(sonCategoryVo);
                }
                categoryVo.setChildren(sonCategoryVoList);
                categoryVoList.add(categoryVo);
            }
        }
        return categoryVoList;
    }

    private Map<Integer, List<MarketCategory>> groupByPid(List<MarketCategory> marketCategoryList) {
        HashMap<Integer, List<MarketCategory>> categoryGroupByPidMap = new HashMap<>();
        for (MarketCategory marketCategory : marketCategoryList) {
            Integer pid = marketCategory.getPid();
            List<MarketCategory> categoryListOfPid = categoryGroupByPidMap.get(pid);
            if (categoryListOfPid == null) {
                categoryListOfPid = new ArrayList<>();
                categoryGroupByPidMap.put(pid, categoryListOfPid);
            }
            categoryListOfPid.add(marketCategory);
        }
        return categoryGroupByPidMap;
    }

    @Override
    public List<BrandVo> brandList() {
        SqlSession session = MybatisUtil.getSession();
        MarketBrandMapper mapper = session.getMapper(MarketBrandMapper.class);
        List<MarketBrand> marketBrands = mapper.selectByExample(new MarketBrandExample());
        session.commit();
        session.close();
        List<BrandVo> brandVoList = new ArrayList<>();
        for (MarketBrand marketBrand : marketBrands) {
            BrandVo brandVo = new BrandVo(marketBrand.getId(), marketBrand.getName());
            brandVoList.add(brandVo);
        }
        return brandVoList;
    }

    @Override
    public List<MarketGoodsSpecification> getGoodsSpecifications(String id) {
        SqlSession session = MybatisUtil.getSession();
        MarketGoodsSpecificationMapper mapper = session.getMapper(MarketGoodsSpecificationMapper.class);
        MarketGoodsSpecificationExample marketGoodsSpecificationExample = new MarketGoodsSpecificationExample();
        MarketGoodsSpecificationExample.Criteria criteria = marketGoodsSpecificationExample.createCriteria();
        criteria.andGoodsIdEqualTo(Integer.parseInt(id));
        List<MarketGoodsSpecification> marketGoodsSpecifications = mapper.selectByExample(marketGoodsSpecificationExample);
        session.commit();
        session.close();
        return marketGoodsSpecifications;
    }

    @Override
    public List<MarketGoodsProduct> getGoodsProducts(String id) {
        SqlSession session = MybatisUtil.getSession();
        MarketGoodsProductMapper mapper = session.getMapper(MarketGoodsProductMapper.class);
        MarketGoodsProductExample marketGoodsProductExample = new MarketGoodsProductExample();
        MarketGoodsProductExample.Criteria criteria = marketGoodsProductExample.createCriteria();
        criteria.andGoodsIdEqualTo(Integer.parseInt(id));
        List<MarketGoodsProduct> marketGoodsProducts = mapper.selectByExample(marketGoodsProductExample);
        session.commit();
        session.close();
        return marketGoodsProducts;
    }

    @Override
    public List<MarketGoodsAttribute> getGoodsAttributes(String id) {
        SqlSession session = MybatisUtil.getSession();
        MarketGoodsAttributeMapper mapper = session.getMapper(MarketGoodsAttributeMapper.class);
        MarketGoodsAttributeExample marketGoodsAttributeExample = new MarketGoodsAttributeExample();
        MarketGoodsAttributeExample.Criteria criteria = marketGoodsAttributeExample.createCriteria();
        criteria.andGoodsIdEqualTo(Integer.parseInt(id));
        List<MarketGoodsAttribute> marketGoodsAttributes = mapper.selectByExample(marketGoodsAttributeExample);
        session.commit();
        session.close();
        return marketGoodsAttributes;
    }

    @Override
    public MarketCategory findPid(Integer categoryId) {
        SqlSession session = MybatisUtil.getSession();
        MarketCategoryMapper mapper = session.getMapper(MarketCategoryMapper.class);
        MarketCategoryExample marketCategoryExample = new MarketCategoryExample();
        MarketCategoryExample.Criteria criteria = marketCategoryExample.createCriteria();
        //select pid from market_category where id = ?
        if (categoryId != null) {
            criteria.andIdEqualTo(categoryId);
        }
        MarketCategory marketCategory = mapper.selectOneByExample(marketCategoryExample);
        session.commit();
        session.close();
        return marketCategory;

    }

    @Override
    public void updateGoods(MarketGoods goods, List<MarketGoodsAttribute> attributes, List<MarketGoodsProduct> products, List<MarketGoodsSpecification> specifications) {
        goods.setDeleted(false);
        SqlSession session = MybatisUtil.getSession();
        MarketGoodsMapper goodsMapper = session.getMapper(MarketGoodsMapper.class);
        MarketGoodsAttributeMapper goodsAttributeMapper = session.getMapper(MarketGoodsAttributeMapper.class);
        MarketGoodsProductMapper goodsProductMapper = session.getMapper(MarketGoodsProductMapper.class);
        MarketGoodsSpecificationMapper goodsSpecificationMapper = session.getMapper(MarketGoodsSpecificationMapper.class);

        MarketGoodsExample marketGoodsExample = new MarketGoodsExample();
        MarketGoodsExample.Criteria criteria = marketGoodsExample.createCriteria();
        criteria.andIdEqualTo(goods.getId());
        goodsMapper.updateByExampleSelective(goods, marketGoodsExample);

        for (MarketGoodsAttribute attribute : attributes) {
            attribute.setUpdateTime(LocalDateTime.now());
            goodsAttributeMapper.updateByPrimaryKeySelective(attribute);
        }

        for (MarketGoodsProduct product : products) {
            product.setUpdateTime(LocalDateTime.now());
            goodsProductMapper.updateByPrimaryKeySelective(product);
        }

        for (MarketGoodsSpecification specification : specifications) {
            specification.setUpdateTime(LocalDateTime.now());
            goodsSpecificationMapper.updateByPrimaryKeySelective(specification);
        }

        session.commit();
        session.close();
    }

    @Override
    public void insert(MarketGoods goods, List<MarketGoodsAttribute> attributes, List<MarketGoodsSpecification> specifications, List<MarketGoodsProduct> products) {
        goods.setAddTime(LocalDateTime.now());
        goods.setUpdateTime(LocalDateTime.now());
        goods.setDeleted(false);
        // 设置最低价格
        BigDecimal retailPrice = products.get(0).getPrice();
        for (int i = 0; i < products.size(); i++) {
            // 只要遇到一个更低的价格，就把更低的价格赋值给retailPrice
            BigDecimal price = products.get(i).getPrice();
            if(retailPrice.compareTo(price)==1){
                retailPrice=price;
            }
        }
        goods.setRetailPrice(retailPrice);

        SqlSession session = MybatisUtil.getSession();
        MarketGoodsMapper goodsMapper = session.getMapper(MarketGoodsMapper.class);
        MarketGoodsAttributeMapper attributeMapper = session.getMapper(MarketGoodsAttributeMapper.class);
        MarketGoodsSpecificationMapper specificationMapper = session.getMapper(MarketGoodsSpecificationMapper.class);
        MarketGoodsProductMapper productMapper = session.getMapper(MarketGoodsProductMapper.class);

        // 插入完毕之后，当前商品便会有编号了，所以接下来的参数、规格、货品就可以设置goodsId了
        int flag=0;
        try{
            goodsMapper.insert(goods);
            // 插入了attribute表
            for (MarketGoodsAttribute attribute : attributes) {
                attribute.setGoodsId(goods.getId());
                attribute.setAddTime(LocalDateTime.now());
                attribute.setUpdateTime(LocalDateTime.now());
                attribute.setDeleted(false);
                attributeMapper.insert(attribute);
            }
            for (MarketGoodsSpecification specification : specifications) {
                specification.setGoodsId(goods.getId());
                specification.setAddTime(LocalDateTime.now());
                specification.setUpdateTime(LocalDateTime.now());
                specification.setDeleted(false);
                specificationMapper.insert(specification);
            }
            for (MarketGoodsProduct product : products) {
                product.setGoodsId(goods.getId());
                product.setAddTime(LocalDateTime.now());
                product.setUpdateTime(LocalDateTime.now());
                product.setDeleted(false);
                productMapper.insert(product);
            }
            session.commit();

        }catch (Exception e){
            e.printStackTrace();
            flag=1;
            session.rollback();
        }finally {
            session.close();
        }
    }
}
